<template>
    <el-dialog
        v-model="isShow"
        :align-center="true"
        :close-on-click-modal="false"
        :destroy-on-close="true"
        :title="formType === 'add' ? '添加角色' : '编辑角色'"
        class="dialog-box"
        @close="onCloseDialog"
    >
        <el-scrollbar max-height="450px">
            <el-form label-width="100" ref="formRef" :model="roleForm" :rules="rules">
                <el-form-item prop="name" label="角色名称">
                    <el-input v-model="roleForm.name" placeholder="请输入角色名称" clearable></el-input>
                </el-form-item>
                <el-form-item prop="identifying" label="角色标识">
                    <el-select v-model="roleForm.identifying" clearable placeholder="请选择角色标识">
                        <el-option v-for="(item, index) in roleIdentifyingOptions" :key="index" :label="item.label" :value="item.value"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="菜单权限">
                    <el-tree-select
                        v-model="roleForm.menuIds"
                        placeholder="请选择菜单权限"
                        :data="menus"
                        node-key="id"
                        :props="{ label: 'title' }"
                        :default-checked-keys="roleForm.menuIds"
                        default-expand-all
                        render-after-expand
                        show-checkbox
                        clearable
                        multiple
                        filterable
                        collapse-tags
                        collapse-tags-tooltip
                        @check="onCheckHandler"
                    ></el-tree-select>
                </el-form-item>
                <el-form-item prop="description" label="角色描述">
                    <el-input type="textarea" v-model="roleForm.description" placeholder="请输入角色描述"></el-input>
                </el-form-item>

                <el-form-item label="是否启用">
                    <el-switch v-model="roleForm.isEnabled" />
                </el-form-item>
            </el-form>
        </el-scrollbar>
        <template #footer>
            <el-button @click="onCancel">取消</el-button>
            <el-button @click="onConfirm" type="primary">确认</el-button>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { MenuType } from '@/api/auth/menu/types'
import { RoleForm } from '@/api/auth/role/types'
import { FormInstance, FormRules } from 'element-plus'

const emit = defineEmits<{ onTableAction: [action: TableActionType, params: any] }>()
// 是否显示dialog
const isShow = ref(false)
// 表单类型
const formType = ref<FormType>('add')
// 表单实例 Ref
const formRef = ref<FormInstance>()
// 表单初始数据
const initform: Partial<RoleForm> = {
    id: undefined,
    name: '',
    identifying: undefined,
    description: '',
    menuIds: [],
    isEnabled: true,
}
const menus = ref<Partial<MenuType>[]>()

const roleIdentifyingOptions: SelectOptions[] = [
    {
        label: '超级管理员',
        value: 'SuperAdmin',
    },
    {
        label: '系统管理员',
        value: 'SystemAdmin',
    },
    {
        label: '用户管理员',
        value: 'UserAdmin',
    },
    {
        label: '族库管理员',
        value: 'FamilyLibraryAdmin',
    },
    {
        label: '数据安全管理员',
        value: 'DateSecurityAdmin',
    },
    {
        label: '会员',
        value: 'Member',
    },
    {
        label: '普通账号',
        value: 'NormalUser',
    },
]
// 表单数据
const roleForm = reactive<Partial<RoleForm>>({ ...initform })
// 表单校验规则
const rules = reactive<FormRules<RoleForm>>({
    name: [
        {
            type: 'string',
            required: true,
            message: '角色名称不能为空',
            trigger: 'change',
        },
    ],
    identifying: [
        {
            type: 'string',
            required: true,
            message: '角色标识不能为空',
            trigger: 'change',
        },
    ],
})

watch(
    () => isShow.value,
    () => {
        if (isShow.value) {
            getMenus()
        }
    },
)

const getMenus = async () => {
    const result = await getAllMenus()
    if (result.isSuccess) {
        menus.value = [{ id: 0, title: '全部', children: result.data }]
    }
}
// 下拉选择树选择改变事件
const onCheckHandler = (obj: any, node: any) => {
    roleForm.menuIds = node.checkedKeys.filter((item: any) => item !== 0)
}

// 打开dialog
const onOpenDialog = (action: FormType, row?: RoleForm) => {
    formType.value = action
    if (action !== 'add' && row) {
        Object.assign(roleForm, row)
    }
    isShow.value = true
}
// 关闭dialog
const onCloseDialog = () => {
    isShow.value = false
    Object.assign(roleForm, initform)
}
// 取消
const onCancel = () => onCloseDialog()
// 完成确认
const onConfirm = async () => {
    await formRef.value?.validate()

    if (roleForm.menuIds && roleForm.menuIds.length !== 0 && menus.value && menus.value?.length !== 0) {
        const flatArr = getFlatArray(menus.value)
        flatArr.forEach((item) => {
            if (!item.parentId || item.parentId === 0) {
                return
            }
            if (roleForm.menuIds?.includes(item.id)) {
                const parentArr = getAncestorIds(flatArr, item, false)
                if (parentArr.length !== 0) {
                    roleForm.menuIds.push(...parentArr)
                }
            }
        })
        roleForm.menuIds = [...new Set(roleForm.menuIds)]
    }

    emit('onTableAction', 'addOrEditSubmit', roleForm)
}
defineExpose({
    onOpenDialog,
    onCloseDialog,
})
</script>

<style lang="scss" scoped></style>
